package com.loveyukari.dao.impl;

import com.loveyukari.dao.YubaPostDao;
import com.loveyukari.model.YubaPost;
import com.loveyukari.model.YubaPostComment;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

@Repository
public class JdbcYubaPostDao extends BaseDao implements YubaPostDao {

    private RowMapper<YubaPost> yubaPostsRowMapper = new RowMapper<YubaPost>() {
        @Override
        public YubaPost mapRow(ResultSet rs, int rowNum) throws SQLException {
            YubaPost yubaPost = new YubaPost();
            yubaPost.setPostId(rs.getString("post_id"));
            yubaPost.setAuthId(rs.getInt("auth_id"));
            yubaPost.setNickname(rs.getString("nickname"));
            yubaPost.setTitle(rs.getString("title"));
            yubaPost.setContent(rs.getString("content"));
            yubaPost.setComments(rs.getInt("comments"));
            yubaPost.setLikes(rs.getInt("likes"));
            yubaPost.setCreateTime(rs.getTimestamp("create_time"));
            return yubaPost;
        }
    };

    private RowMapper<YubaPostComment> yubaPostsCommentRowMapper = new RowMapper<YubaPostComment>() {
        @Override
        public YubaPostComment mapRow(ResultSet rs, int rowNum) throws SQLException {
            YubaPostComment yubaPostComment = new YubaPostComment();
            yubaPostComment.setCommentId(rs.getString("comment_id"));
            yubaPostComment.setPostId(rs.getString("post_id"));
            yubaPostComment.setParentCommentId(rs.getString("parent_comment_id"));
            yubaPostComment.setAuthId(rs.getInt("auth_id"));
            yubaPostComment.setNickname(rs.getString("nickname"));
            yubaPostComment.setContent(rs.getString("content"));
            yubaPostComment.setReplys(rs.getInt("replys"));
            yubaPostComment.setLikes(rs.getInt("likes"));
            yubaPostComment.setCreateTime(rs.getTimestamp("create_time"));
            yubaPostComment.setFloor(rs.getInt("floor"));
            return yubaPostComment;
        }
    };


    @Override
    public YubaPost selectPostById(String postId) {
        String sql = "select * from yuba_posts where post_id = ?";
        List<YubaPost> list = this.getJdbcTemplate().query(sql, yubaPostsRowMapper, postId);
        if (list.isEmpty()){
            return null;
        } else {
            return list.get(0);
        }
    }

    @Override
    public List<YubaPostComment> selectAllCommentByPostId(String postId) {
        String sql = "select * from yuba_posts_comment where post_id = ?";
        return this.getJdbcTemplate().query(sql, yubaPostsCommentRowMapper, postId);
    }


    @Override
    public YubaPostComment selectCommentByCommentId(String commentId) {
        String sql = "select * from yuba_posts_comment where comment_id = ?";
        List<YubaPostComment> list = this.getJdbcTemplate().query(sql, yubaPostsCommentRowMapper, commentId);
        if (list.isEmpty()){
            return null;
        } else {
            return list.get(0);
        }
    }

    @Override
    public void insertPost(YubaPost post) {
        String sql = "insert into yuba_posts(post_id,auth_id,nickname,title,content,create_time) values(?,?,?,?,?,?)";
        this.getJdbcTemplate().update(sql,post.getPostId(),post.getAuthId(),post.getNickname(),post.getTitle(),post.getContent(),post.getCreateTime());
    }

    @Override
    public void insertPostcomment(YubaPostComment postComment) {
        String sql = "insert into yuba_posts_comment(comment_id,post_id,parent_comment_id,auth_id,nickname,content,create_time,floor) values(?,?,?,?,?,?,?,?)";
        this.getJdbcTemplate().update(sql,postComment.getCommentId(),postComment.getPostId(),postComment.getParentCommentId(),postComment.getAuthId(),postComment.getNickname(),postComment.getContent(),postComment.getCreateTime(),postComment.getFloor());

    }


    @Override
    public void updatePostLike(final Map<String, Integer> postIdLikeMap) {
        String sql = "update yuba_posts set likes = ? where post_id = ?";
        this.batchUpdate(sql,postIdLikeMap);

    }

    @Override
    public void updatePostComments(Map<String, Integer> postIdCommentsMap) {
        String sql = "update yuba_posts set comments = ? where post_id = ?";
        this.batchUpdate(sql,postIdCommentsMap);
    }

    @Override
    public void updatePostCreateTime(Map<String, Date> postIdCreateTimeMap) {
        String sql = "update yuba_posts set create_time = ? where post_id = ?";
        this.batchUpdate(sql,postIdCreateTimeMap);
    }

    @Override
    public void updatePostCommentReplys(Map<String, Integer> commentIdReplysMap) {
        String sql = "update yuba_posts_comment set replys = ? where post_id = ?";
        this.batchUpdate(sql,commentIdReplysMap);
    }

    @Override
    public void updatePostCommentLike(final Map<String, Integer> commentIdLikeMap) {
        String sql = "update yuba_posts_comment set likes = ? where post_id = ?";
        this.batchUpdate(sql,commentIdLikeMap);
    }

    private void batchUpdate(String sql,final Map map ){
        final ArrayList<String> keys = new ArrayList<String>(map.keySet());
        this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                String key = keys.get(i);
                Object value = map.get(key);
                ps.setObject(1,value);
                ps.setString(2,key);
            }
            @Override
            public int getBatchSize() {
                return keys.size();
            }
        });
    }

    @Override
    public void updatePostCommentStatusByPostFloor(Map<String, List<Integer>> postFloorsMap, int status) {
        String sql = "update yuba_posts_comment set status = ? where comment_id = ? and floor = ?";
        ArrayList<Object[]> args = new ArrayList<Object[]>();
        Set<String> commentIds = postFloorsMap.keySet();
        for (String commentId :
                commentIds) {
            List<Integer> floors = postFloorsMap.get(commentId);
            for (Integer floor :
                    floors) {
                Object[] arg = new Object[3];
                arg[0] = status;
                arg[1] = commentId;
                arg[2] = floor;
                args.add(arg);
            }
        }
        this.getJdbcTemplate().batchUpdate(sql,args);
    }
}
